/**
 * 汉字五行查询工具
 * 通过在线API查询汉字对应的五行属性
 */

// 缓存已查询过的汉字五行属性，避免重复请求
const wuxingCache = {};

/**
 * 查询单个汉字的五行属性
 * @param {string} char - 要查询的汉字
 * @returns {Promise<string>} - 返回表示五行属性的字符串：'金'、'木'、'水'、'火'、'土'
 */
function queryCharWuxing(char) {
  return new Promise((resolve, reject) => {
    // 如果已经在缓存中，直接返回结果
    if (wuxingCache[char]) {
      console.log(`【五行查询】汉字"${char}"命中缓存: ${wuxingCache[char]}`);
      resolve(wuxingCache[char]);
      return;
    }
    
    // 使用本地数据作为备选
    const localData = getLocalWuxingData();
    if (localData[char]) {
      console.log(`【五行查询】汉字"${char}"使用本地数据: ${localData[char]}`);
      // 缓存本地结果
      wuxingCache[char] = localData[char];
      resolve(localData[char]);
      return;
    }
    
    // 构建请求URL
    const url = `https://www.zxgongju.com/wuxing/wx_${encodeURIComponent(char)}.html`;
    console.log(`【五行查询】正在请求汉字"${char}"的五行属性，URL: ${url}`);
    
    // 请求超时控制
    const timeout = 5000; // 5秒超时
    let isTimeout = false;
    
    // 设置超时定时器
    const timeoutTimer = setTimeout(() => {
      isTimeout = true;
      console.log(`【五行查询】汉字"${char}"请求超时`);
      
      // 超时后返回固定值
      const fallbackElement = getFallbackElement(char);
      wuxingCache[char] = fallbackElement;
      console.log(`【五行查询】汉字"${char}"超时，使用备选五行: ${fallbackElement}`);
      resolve(fallbackElement);
    }, timeout);
    
    // 发起请求
    wx.request({
      url: url,
      timeout: timeout, // 设置请求超时
      success: (res) => {
        // 清除超时定时器
        clearTimeout(timeoutTimer);
        
        // 如果已经触发了超时处理，则不再处理响应
        if (isTimeout) return;
        
        console.log(`【五行查询】汉字"${char}"请求成功，正在解析数据...`);
        try {
          // 解析HTML获取五行属性
          const wuxing = parseWuxingFromHtml(res.data, char);
          
          // 缓存结果
          wuxingCache[char] = wuxing;
          console.log(`【五行查询】汉字"${char}"的五行属性已缓存: ${wuxing}`);
          
          resolve(wuxing);
        } catch (error) {
          console.error(`【五行查询】解析汉字"${char}"五行出错: ${error.message}`);
          
          // 解析失败使用备选值
          const fallbackElement = getFallbackElement(char);
          wuxingCache[char] = fallbackElement;
          console.log(`【五行查询】汉字"${char}"解析失败，使用备选五行: ${fallbackElement}`);
          resolve(fallbackElement);
        }
      },
      fail: (error) => {
        // 清除超时定时器
        clearTimeout(timeoutTimer);
        
        // 如果已经触发了超时处理，则不再处理错误
        if (isTimeout) return;
        
        console.error(`【五行查询】请求汉字"${char}"五行API失败: ${error.errMsg}`);
        
        // 请求失败使用备选值
        const fallbackElement = getFallbackElement(char);
        wuxingCache[char] = fallbackElement;
        console.log(`【五行查询】汉字"${char}"请求失败，使用备选五行: ${fallbackElement}`);
        resolve(fallbackElement);
      }
    });
  });
}

/**
 * 从HTML中解析出汉字的五行属性
 * @param {string} html - API返回的HTML内容
 * @param {string} char - 查询的汉字，用于错误提示
 * @returns {string} - 五行属性
 */
function parseWuxingFromHtml(html, char) {
  // 使用正则表达式匹配"<span>彬的五行：</span> 木"这种格式
  const regex = new RegExp(`<span>${char}的五行：<\/span>\\s*([金木水火土])`, 'i');
  const match = html.match(regex);
  
  if (match && match[1]) {
    console.log(`【五行查询】汉字"${char}"的五行属性是: ${match[1]}`);
    return match[1];
  }
  
  // 尝试使用更宽松的正则表达式
  const fallbackRegex = /<span>.*?的五行：<\/span>\s*([金木水火土])/i;
  const fallbackMatch = html.match(fallbackRegex);
  
  if (fallbackMatch && fallbackMatch[1]) {
    console.log(`【五行查询】汉字"${char}"的五行属性是: ${fallbackMatch[1]} (使用备用正则匹配)`);
    return fallbackMatch[1];
  }
  
  console.error(`【五行查询】无法解析汉字"${char}"的五行属性`);
  throw new Error(`无法从HTML中解析出汉字"${char}"的五行属性`);
}

/**
 * 批量查询多个汉字的五行属性
 * @param {string} chars - 要查询的汉字字符串
 * @returns {Promise<Object>} - 返回包含每个字对应五行属性的对象
 */
function queryMultipleCharsWuxing(chars) {
  // 转换为字符数组并去重
  const uniqueChars = [...new Set([...chars])];
  console.log(`【五行查询】开始批量查询${chars.length}个汉字的五行属性，去重后为${uniqueChars.length}个: ${uniqueChars.join('')}`);
  
  // 创建每个字符的查询Promise
  const promises = uniqueChars.map(char => {
    return queryCharWuxing(char)
      .then(wuxing => {
        console.log(`【五行查询】汉字"${char}"查询成功: ${wuxing}`);
        return { char, wuxing };
      })
      .catch(error => {
        console.error(`【五行查询】汉字"${char}"查询失败: ${error.message || '未知错误'}`);
        return { char, wuxing: '未知' }; // 查询失败时设为未知
      });
  });
  
  // 等待所有Promise完成
  return Promise.all(promises)
    .then(results => {
      // 将结果转化为对象形式
      const resultMap = {};
      results.forEach(item => {
        resultMap[item.char] = item.wuxing;
      });
      
      console.log(`【五行查询】批量查询完成，结果: `, resultMap);
      return resultMap;
    });
}

/**
 * 获取本地常用汉字五行数据
 * 用于在无网络或请求失败时提供备选数据
 * @returns {Object} - 包含汉字和对应五行的映射对象
 */
function getLocalWuxingData() {
  return {
    '李': '木', '王': '水', '张': '木', '刘': '金', '陈': '土',
    '杨': '木', '赵': '火', '黄': '土', '周': '火', '吴': '水',
    '马': '火', '孙': '金', '胡': '水', '朱': '火', '林': '木',
    '郭': '水', '何': '火', '高': '土', '罗': '火', '郑': '火',
    '梁': '火', '谢': '水', '宋': '火', '唐': '火', '许': '水',
    '韩': '水', '冯': '水', '邓': '火', '曹': '火', '彭': '水',
    '曾': '火', '肖': '火', '田': '土', '江': '水', '董': '木',
    '袁': '土', '潘': '水', '蔡': '木', '蒋': '木', '余': '土',
    '杜': '木', '叶': '木', '程': '火', '苏': '水', '魏': '火',
    '吕': '火', '丁': '火', '任': '火', '沈': '水', '姚': '火',
    '卢': '火', '姜': '土', '崔': '金', '钟': '金', '谭': '水',
    '陆': '土', '范': '水', '汪': '水', '廖': '火', '石': '土',
    '金': '金', '明': '火', '思': '木', '维': '土', '华': '木',
    '伟': '土', '嘉': '木', '佳': '木', '志': '火', '强': '金',
    '慧': '水', '美': '土', '英': '木', '健': '木', '文': '水',
    '静': '金', '丽': '火', '芳': '木', '龙': '火', '春': '木',
    '秀': '金', '峰': '土', '杰': '木', '欣': '金', '涛': '水',
    '敏': '水', '军': '水', '勇': '土', '磊': '土', '洋': '水',
    '刚': '金', '平': '火', '燕': '火', '洁': '水', '莉': '木',
    '艳': '火', '超': '火', '梅': '木', '琳': '木', '辉': '火',
    '宇': '土', '鑫': '金', '鹏': '水', '婷': '火', '芹': '木',
    '露': '水', '珊': '金', '宁': '火', '霞': '水', '鸿': '水',
    '莹': '金', '倩': '金', '颖': '木', '婧': '金', '雪': '水',
    '佩': '水', '瑶': '金', '璐': '金', '娜': '土', '玲': '金',
    '诗': '金', '茜': '木', '彬': '木'
  };
}

/**
 * 查询汉字的五行属性，优先使用本地数据，无数据时再请求网络
 * @param {string} char - 要查询的汉字
 * @returns {Promise<string>} - 返回表示五行属性的字符串
 */
function getCharWuxing(char) {
  const localData = getLocalWuxingData();
  
  if (localData[char]) {
    console.log(`【五行查询】汉字"${char}"使用本地数据: ${localData[char]}`);
    return Promise.resolve(localData[char]);
  }
  
  console.log(`【五行查询】汉字"${char}"本地无数据，正在请求网络...`);
  return queryCharWuxing(char)
    .catch(error => {
      console.error(`【五行查询】网络查询汉字"${char}"五行属性失败，将返回默认值:`, error);
      return '未知';
    });
}

/**
 * 根据汉字获取备选的五行属性
 * 在网络请求失败或超时时使用
 * @param {string} char - 汉字
 * @returns {string} - 备选的五行属性
 */
function getFallbackElement(char) {
  // 按照笔画数取模，随机分配五行
  const elements = ['金', '木', '水', '火', '土'];
  const charCode = char.charCodeAt(0);
  const index = charCode % 5;
  return elements[index];
}

/**
 * 分析名字与喜用神的匹配度
 * @param {string} name - 名字字符串
 * @param {Array<string>} favElements - 喜用神数组，如 ['金', '木']
 * @returns {Promise<Object>} - 返回分析结果对象
 */
function analyzeNameWuxingMatch(name, favElements) {
  // 将名字拆分成字符数组
  const chars = [...name];
  console.log(`【五行匹配】开始分析名字"${name}"与喜用神${JSON.stringify(favElements)}的匹配度`);
  
  // 添加超时控制
  return new Promise((resolve) => {
    // 设置15秒超时
    const timeoutTimer = setTimeout(() => {
      console.log(`【五行匹配】分析超时，返回默认结果`);
      
      // 超时返回默认结果
      resolve({
        score: 70, // 默认给一个中等分数
        charElements: chars.map(char => ({
          char,
          element: '未知'
        })),
        matchCount: 0,
        elementCount: 0
      });
    }, 15000);
    
    // 获取所有汉字的五行属性
    queryMultipleCharsWuxing(name)
      .then(wuxingMap => {
        // 清除超时定时器
        clearTimeout(timeoutTimer);
        
        let matchCount = 0;
        let elementCount = 0;
        let charElements = [];
        
        console.log(`【五行匹配】名字"${name}"的五行属性映射:`, wuxingMap);
        
        // 分析每个字符
        chars.forEach(char => {
          if (wuxingMap[char] && wuxingMap[char] !== '未知') {
            elementCount++;
            const charElement = wuxingMap[char];
            
            // 检查是否匹配任一喜用神元素
            const isMatch = favElements.includes(charElement);
            if (isMatch) {
              matchCount++;
            }
            
            console.log(`【五行匹配】字符"${char}"的五行是"${charElement}"，${isMatch ? '匹配' : '不匹配'}喜用神`);
            
            charElements.push({
              char,
              element: charElement
            });
          } else {
            console.log(`【五行匹配】字符"${char}"无五行数据或为未知`);
            
            // 对于未知五行的字符，使用备选值
            const fallbackElement = getFallbackElement(char);
            const isMatch = favElements.includes(fallbackElement);
            elementCount++;
            if (isMatch) {
              matchCount++;
            }
            
            charElements.push({
              char,
              element: fallbackElement
            });
          }
        });
        
        // 计算匹配度评分
        const matchRate = elementCount > 0 ? (matchCount / elementCount) : 0;
        const score = Math.round(matchRate * 100);
        
        console.log(`【五行匹配】匹配统计: 总字符${chars.length}个, 有五行数据${elementCount}个, 匹配喜用神${matchCount}个, 匹配率${(matchRate * 100).toFixed(2)}%, 得分${score}分`);
        
        resolve({
          score,
          charElements,
          matchCount,
          elementCount
        });
      })
      .catch(error => {
        // 清除超时定时器
        clearTimeout(timeoutTimer);
        
        console.error(`【五行匹配】分析过程出错: ${error.message || '未知错误'}`);
        
        // 出错时返回默认结果
        resolve({
          score: 60, // 默认给一个中等偏下分数
          charElements: chars.map(char => ({
            char,
            element: '未知'
          })),
          matchCount: 0,
          elementCount: 0
        });
      });
  });
}

module.exports = {
  queryCharWuxing,
  queryMultipleCharsWuxing,
  getLocalWuxingData,
  getCharWuxing,
  analyzeNameWuxingMatch
}; 